#include "Rainbow_Table.h"
#include "misc.h"
#include "DEHT.h"
#include "generator.h"


int main(int argc, char **argv){
	DEHT *deht = NULL;
	Rule *rule = NULL;
	rainbowTablePref rt;
	BasicHashFunctionPtr h = NULL;
	unsigned char *hBuffer = NULL, *p = NULL;
	char buffer[80] = {0}, hexBuffer[160] = {0}, pswdBuffer[80] = {0};
	int hSize = 0;

	if (argc != 2){
		fprintf(stderr, "Error: Usage crack_using_rainbow_table <filenames prefix>\n");
		return 0;
	}

	rt.seedArr = NULL;

	deht = load_DEHT_from_files(argv[1], hash1, hash2);
	if (deht == NULL){
		return 0;
	}
	if (read_DEHT_pointers_table(deht) == DEHT_STATUS_FAIL){
		lock_DEHT_files(deht);
		fprintf(stderr, "ERROR: unable to read pointers table from DEHT\n");
		return 0;
	}

	if (readRainbowDataToDEHT(deht, &rt, &rule) == 0){
		lock_DEHT_files(deht);
		fprintf(stderr, "ERROR: unable to read rainbow-table data from DEHT\n");
		return 0;
	}

	parseHashFunction(deht->header.sDictionaryName, &h, &hSize);
	if (h == NULL){
		lock_DEHT_files(deht);
		free(rt.seedArr);
		free_PPRule(rule);
		fprintf(stderr, "Error: Hash %s is not supported\n", deht->header.sDictionaryName);
		return 0;
	}
	hBuffer = (unsigned char *)calloc(hSize, sizeof(unsigned char));
	if (hBuffer == NULL){
		lock_DEHT_files(deht);
		free(rt.seedArr);
		free_PPRule(rule);
		fprintf(stderr, "mem. allocation failure\n");
		return 0;
	}

	while (1){
		printf(">> ");
		readBuffer(buffer);
		if (strcmp(buffer,"quit") == 0) break;
		else if (strcmp(buffer, "") == 0)
			continue;
		else if (verifyHexa(buffer) == 1) {
			hexa2binary(buffer, hBuffer, hSize);
			p = (unsigned char *)hBuffer;
		}
		else if (*buffer == '!'){
			binary2hexa((unsigned char *)(buffer+1), strlen(buffer)-1, hexBuffer, 80);
			printf("\tIn hexa password is %s\n", hexBuffer);
			cryptHash(h, (buffer+1), hBuffer);
			p = hBuffer;
		}
		else {
			fprintf(stderr, "Commands are either hexa, !password or quit.\n");
			continue;
		}
		if (query_RT(deht, &rt, rule, p, pswdBuffer) == 0){
			printf("Sorry but this hash doesn't appears in pre-processing\n");
			continue;
		}
		else {
			
			printf("Try to login with password \"%s\"\n", pswdBuffer);
			continue;
		}
		
	}

	free(hBuffer);
	lock_DEHT_files(deht);
	free(rt.seedArr);
	free_PPRule(rule);
	return 1;
}
